<!--
  编辑器画布组件
  负责图层渲染和交互
-->
<template>
  <div class="editor-canvas" ref="containerRef">
    <!-- 画布容器 -->
    <div 
      class="canvas-container"
      :style="containerStyle"
      @wheel="handleWheel"
      @mousedown="handleMouseDown"
      @mousemove="handleMouseMove"
      @mouseup="handleMouseUp"
      @contextmenu="handleContextMenu"
    >
      <!-- 主画布 -->
      <canvas 
        ref="canvasRef"
        :width="canvasWidth"
        :height="canvasHeight"
        :style="canvasStyle"
        @dragover="handleDragOver"
        @drop="handleDrop"
      />
      
      <!-- 选择框 -->
      <div 
        v-if="selectionBox"
        class="selection-box"
        :style="selectionBoxStyle"
      />
      
      <!-- 变换控制器 -->
      <TransformControls
        v-if="selectedLayers.length > 0"
        :layers="selectedLayers"
        :viewport="viewport"
        @transform="handleTransform"
      />
      
      <!-- 画布工具提示 -->
      <div v-if="showCanvasEmpty" class="canvas-placeholder">
        <n-icon size="48" color="#ccc">
          <ImagesOutline />
        </n-icon>
        <p>从左侧拖拽素材到此处开始创作</p>
      </div>
    </div>
    
    <!-- 剪映风格播放控制器 -->
    <JianyingStylePlaybackControls
      class="embedded-playback-controls"
      @play="handlePlay"
      @pause="handlePause"
      @stop="handleStop"
    />

    <!-- 画布信息显示 -->
    <div class="canvas-info">
      <n-space size="small">
        <n-text depth="3">{{ Math.round(viewport.zoom * 100) }}%</n-text>
        <n-text depth="3">{{ canvasWidth }}×{{ canvasHeight }}</n-text>
        <n-text depth="3" v-if="renderStats">{{ Math.round(renderStats.fps) }} FPS</n-text>
        <n-text depth="3" v-if="renderStats">{{ renderStats.layersRendered }} 图层</n-text>
        <n-text depth="3" :style="{ color: isRenderingActive ? '#18a058' : '#d03050' }">
          {{ isRenderingActive ? '实时渲染' : '静态渲染' }}
        </n-text>
      </n-space>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount, nextTick, watch } from 'vue'
import { NIcon, NText, NSpace } from 'naive-ui'
import { ImagesOutline } from '@vicons/ionicons5'
import { useEditorStore } from '../../stores/editor'
import { RenderEngine, type LayerData as LayerRenderData, type RenderStats } from '../../core/engine/renderer'
import TransformControls from './TransformControls.vue'
import JianyingStylePlaybackControls from './JianyingStylePlaybackControls.vue'
import { message } from '../../utils/message'

// 事件定义
const emit = defineEmits(['layer-select', 'layer-transform', 'play', 'pause', 'stop'])

// 状态管理
const editorStore = useEditorStore()

// 组件引用
const containerRef = ref<HTMLElement | null>(null)
const canvasRef = ref<HTMLCanvasElement | null>(null)

// 渲染引擎
let renderEngine: RenderEngine | null = null
const renderStats = ref<RenderStats | null>(null)

// 交互状态
const isDragging = ref(false)
const dragStart = ref({ x: 0, y: 0 })
const dragType = ref<'pan' | 'select' | 'transform'>('pan')
const selectionBox = ref<{ x: number; y: number; width: number; height: number } | null>(null)

// 计算属性
const viewport = computed(() => editorStore.viewport)
const selectedLayers = computed(() => 
  editorStore.layers.filter(layer => 
    editorStore.selection.selectedLayers.includes(layer.id)
  )
)
const showCanvasEmpty = computed(() => editorStore.layers.length === 0)

const canvasWidth = computed(() => viewport.value.width * viewport.value.zoom)
const canvasHeight = computed(() => viewport.value.height * viewport.value.zoom)

const containerStyle = computed(() => ({
  transform: `translate(${viewport.value.panX}px, ${viewport.value.panY}px)`,
  cursor: isDragging.value ? 'grabbing' : 'grab'
}))

const canvasStyle = computed(() => ({
  width: `${canvasWidth.value}px`,
  height: `${canvasHeight.value}px`,
  boxShadow: '0 0 20px rgba(0, 0, 0, 0.1)'
}))

const selectionBoxStyle = computed(() => {
  if (!selectionBox.value) return {}
  
  return {
    left: `${selectionBox.value.x}px`,
    top: `${selectionBox.value.y}px`,
    width: `${selectionBox.value.width}px`,
    height: `${selectionBox.value.height}px`
  }
})

// 渲染状态
const isRenderingActive = ref(true)
const animationFrameId = ref<number | null>(null)

// 渲染方法
const render = () => {
  if (!renderEngine) return

  const layersData: LayerRenderData[] = editorStore.visibleLayers.map(layer => ({
    ...layer,
    zIndex: layer.zIndex || 0
  }))

  renderEngine.render(layersData, editorStore.showGrid, editorStore.gridSize)
  renderStats.value = renderEngine.getStats()
}

// 持续渲染循环
const startRenderLoop = () => {
  const renderLoop = () => {
    if (!isRenderingActive.value) return

    render()
    animationFrameId.value = requestAnimationFrame(renderLoop)
  }

  renderLoop()
}

// 停止渲染循环
const stopRenderLoop = () => {
  isRenderingActive.value = false
  if (animationFrameId.value) {
    cancelAnimationFrame(animationFrameId.value)
    animationFrameId.value = null
  }
}

// 鼠标事件处理
const handleMouseDown = (event: MouseEvent) => {
  if (!containerRef.value) return
  
  const rect = containerRef.value.getBoundingClientRect()
  const x = event.clientX - rect.left
  const y = event.clientY - rect.top
  
  isDragging.value = true
  dragStart.value = { x, y }
  
  // 检查是否点击了图层
  const clickedLayer = getLayerAtPoint(x, y)
  
  if (clickedLayer) {
    // 选择图层
    emit('layer-select', clickedLayer.id, event.ctrlKey || event.metaKey)
    dragType.value = 'transform'
  } else {
    // 开始框选或平移
    if (event.shiftKey) {
      dragType.value = 'select'
      selectionBox.value = { x, y, width: 0, height: 0 }
    } else {
      dragType.value = 'pan'
    }
  }
  
  event.preventDefault()
}

const handleMouseMove = (event: MouseEvent) => {
  if (!isDragging.value || !containerRef.value) return
  
  const rect = containerRef.value.getBoundingClientRect()
  const x = event.clientX - rect.left
  const y = event.clientY - rect.top
  
  const deltaX = x - dragStart.value.x
  const deltaY = y - dragStart.value.y
  
  if (dragType.value === 'pan') {
    // 平移视口
    editorStore.viewport.panX += deltaX
    editorStore.viewport.panY += deltaY
    dragStart.value = { x, y }
  } else if (dragType.value === 'select') {
    // 更新选择框
    if (selectionBox.value) {
      selectionBox.value.width = deltaX
      selectionBox.value.height = deltaY
    }
  }
}

const handleMouseUp = (event: MouseEvent) => {
  if (!isDragging.value) return
  
  if (dragType.value === 'select' && selectionBox.value) {
    // 完成框选
    const selectedLayerIds = getLayersInBox(selectionBox.value)
    editorStore.clearSelection()
    selectedLayerIds.forEach(id => editorStore.selectLayer(id, true))
    selectionBox.value = null
  }
  
  isDragging.value = false
  dragType.value = 'pan'
}

const handleWheel = (event: WheelEvent) => {
  event.preventDefault()
  
  if (event.ctrlKey || event.metaKey) {
    // 缩放
    const zoomFactor = event.deltaY > 0 ? 0.9 : 1.1
    const newZoom = Math.max(0.1, Math.min(5, viewport.value.zoom * zoomFactor))
    editorStore.viewport.zoom = newZoom
  } else {
    // 平移
    editorStore.viewport.panX -= event.deltaX
    editorStore.viewport.panY -= event.deltaY
  }
}

const handleContextMenu = (event: MouseEvent) => {
  event.preventDefault()
  // TODO: 显示右键菜单
}

// 拖放处理
const handleDragOver = (event: DragEvent) => {
  event.preventDefault()
  if (event.dataTransfer) {
    event.dataTransfer.dropEffect = 'copy'
  }
}

const handleDrop = (event: DragEvent) => {
  event.preventDefault()
  
  if (!event.dataTransfer || !canvasRef.value) return
  
  const data = event.dataTransfer.getData('application/json')
  if (!data) return
  
  try {
    const asset = JSON.parse(data)
    const rect = canvasRef.value.getBoundingClientRect()
    
    // 计算相对于画布的位置
    const x = (event.clientX - rect.left) / viewport.value.zoom
    const y = (event.clientY - rect.top) / viewport.value.zoom
    
    // 创建新图层
    const newLayer = editorStore.addLayer({
      name: asset.name,
      visible: true,
      locked: false,
      type: asset.type,
      position: { x, y },
      scale: { x: 1, y: 1 },
      rotation: 0,
      opacity: 100,
      assetId: asset.id
    })
    
    // 创建对应的轨道
    editorStore.addTrack({
      name: asset.name,
      type: asset.type,
      layerId: newLayer.id,
      visible: true,
      locked: false,
      keyframes: []
    })
    
    // 选择新图层
    editorStore.clearSelection()
    editorStore.selectLayer(newLayer.id)
    
    message.success(`已添加 ${asset.name}`)
    
  } catch (error) {
    console.error('拖放处理失败:', error)
    message.error('添加素材失败')
  }
}

// 变换处理
const handleTransform = (layerId: string, transform: any) => {
  emit('layer-transform', layerId, transform)
}

// 播放控制处理
const handlePlay = () => {
  emit('play')
}

const handlePause = () => {
  emit('pause')
}

const handleStop = () => {
  emit('stop')
}

// 工具方法
const getLayerAtPoint = (x: number, y: number) => {
  if (!renderEngine) return null
  
  // 转换屏幕坐标到画布坐标
  const canvasX = (x - viewport.value.panX) / viewport.value.zoom
  const canvasY = (y - viewport.value.panY) / viewport.value.zoom
  
  // 从上到下检查图层（z-index从高到低）
  const sortedLayers = [...editorStore.visibleLayers].reverse()
  
  for (const layer of sortedLayers) {
    const layerData: LayerRenderData = {
      ...layer,
      zIndex: layer.zIndex || 0
    }

    if (renderEngine.hitTest(canvasX, canvasY, [layerData])) {
      return layer
    }
  }
  
  return null
}

const getLayersInBox = (box: { x: number; y: number; width: number; height: number }) => {
  // TODO: 实现框选逻辑
  return []
}

// 生命周期
onMounted(async () => {
  await nextTick()

  if (canvasRef.value) {
    renderEngine = new RenderEngine(canvasRef.value, {
      width: viewport.value.width,
      height: viewport.value.height,
      backgroundColor: '#f5f5f5'
    })

    // 根据初始渲染模式决定是否启动渲染循环
    isRenderingActive.value = editorStore.isRealTimeRender
    if (editorStore.isRealTimeRender) {
      startRenderLoop()
    } else {
      render() // 静态模式下渲染一次
    }
  }
})

onBeforeUnmount(() => {
  // 停止渲染循环
  stopRenderLoop()

  if (renderEngine) {
    renderEngine.dispose()
  }
})

// 监听渲染模式变化
watch(() => editorStore.isRealTimeRender, (newValue) => {
  isRenderingActive.value = newValue
  if (newValue) {
    startRenderLoop()
  } else {
    stopRenderLoop()
    // 在静态模式下，仍然需要监听变化来触发渲染
    render()
  }
}, { immediate: true })

// 在静态渲染模式下监听变化
watch(() => editorStore.isRealTimeRender, (isRealTime) => {
  if (!isRealTime) {
    // 静态模式下监听变化
    const stopWatchers = [
      watch(() => editorStore.layers, render, { deep: true }),
      watch(() => editorStore.viewport, render, { deep: true }),
      watch(() => editorStore.showGrid, render),
      watch(() => editorStore.gridSize, render)
    ]

    // 当切换回实时模式时，停止这些监听器
    const stopStaticWatchers = watch(() => editorStore.isRealTimeRender, (newIsRealTime) => {
      if (newIsRealTime) {
        stopWatchers.forEach(stop => stop())
        stopStaticWatchers()
      }
    })
  }
})

// 暴露方法
defineExpose({
  render
})
</script>

<style lang="scss" scoped>
.editor-canvas {
  flex: 1;
  position: relative;
  overflow: hidden;
  background: 
    radial-gradient(circle, #ccc 1px, transparent 1px),
    linear-gradient(to right, #f0f0f0 0%, #f8f8f8 100%);
  background-size: 20px 20px;
}

.canvas-container {
  position: absolute;
  top: 50%;
  left: 50%;
  transform-origin: center;
  user-select: none;
}

.selection-box {
  position: absolute;
  border: 2px dashed var(--primary-color);
  background: rgba(var(--primary-color-rgb), 0.1);
  pointer-events: none;
  z-index: 10;
}

.canvas-placeholder {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  color: #999;
  pointer-events: none;
  
  p {
    margin-top: 16px;
    font-size: 14px;
  }
}

.embedded-playback-controls {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 200;
}

.canvas-info {
  position: absolute;
  bottom: 56px; /* 调整位置，避免与播放控制器重叠 */
  left: 8px;
  padding: 4px 8px;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  border-radius: 4px;
  font-size: 12px;
  font-family: monospace;
  z-index: 150;
}
</style>
